// 角度转弧度
export const angle2Rad = (angle) => {
  return (angle * Math.PI) / 180;
};

// 弧度转角度
export const rad2Angle = (rad) => {
  return (rad * 180) / Math.PI;
};

// 地球半径
export const EARTH_RAD = 6378137;

// 4326 转 3857
export const lngLat2Mercator = (lng, lat) => {
  // 经度先转弧度，然后因为 弧度 = 弧长 / 半径 ，得到弧长为 弧长 = 弧度 * 半径
  const x = angle2Rad(lng) * EARTH_RAD;
  // 纬度先转弧度
  const rad = angle2Rad(lat);
  const sin = Math.sin(rad);
  const y = (EARTH_RAD / 2) * Math.log((1 + sin) / (1 - sin));
  return [x, y];
};

// 3857转4326
export const mercator2lngLat = (x, y) => {
  const lng = rad2Angle(x) / EARTH_RAD;
  const lat = rad2Angle(2 * Math.atan(Math.exp(y / EARTH_RAD)) - Math.PI / 2);
  return [lng, lat];
};

// 地球周长
export const EARTH_PERIMETER = 2 * Math.PI * EARTH_RAD;
// 瓦片像素256*256
export const TILE_SIZE = 256;

/* 获取某一层级下的分辨率，即一像素代表多少米
最小的地图等级是0，此时世界地图只由一张瓦片组成。
第1层有4个瓦片，第2层有8个，依次类推...
瓦片等级越高，组成世界地图的瓦片数越多，可以展示的地图越详细。
某一瓦片等级地图的瓦片是由低一级的各瓦片切割成的4个瓦片组成，形成了瓦片金字塔。
https://www.cnblogs.com/mymhj/p/7416773.html
**/
export const getResolution = (n) => {
  // 第0层是1*1瓦片数，第1层是2*2，第2层，2*2*2
  const tileNums = Math.pow(2, n);
  // 一边的总像素值，瓦片数乘以单个瓦片的尺寸
  const tileTotalPx = tileNums * TILE_SIZE;
  // 瓦片的边长等于地球周长，周长除以总像素值，得出一个像素代表实际的多少米
  return EARTH_PERIMETER / tileTotalPx;
};

/**
 * 米除以分辨率得到像素长度，再处理256得到像素行列号
 * 然后瓦片坐标远点在左上角，而投影坐标原点在中心位置，需要进行坐标转换
 * @param {*} x
 * @param {*} y
 * @param {*} z
 * @returns
 */
export const getTileRowAndCol = (x, y, z) => {
  // 转换坐标原点位置
  x += EARTH_PERIMETER / 2;
  y = EARTH_PERIMETER / 2 - y;
  const resolution = getResolution(z);
  const row = Math.floor(x / resolution / TILE_SIZE);
  const col = Math.floor(y / resolution / TILE_SIZE);
  return [row, col];
};

// 计算4326经纬度对应的像素坐标
export const getPxFromLngLat = (lng, lat, z) => {
  let [_x, _y] = lngLat2Mercator(lng, lat); // 4326转3857
  // 转成世界平面图的坐标原点
  _x += EARTH_PERIMETER / 2;
  _y = EARTH_PERIMETER / 2 - _y;
  // 该层级的分辨率
  const resolution = getResolution(z);
  // 米/分辨率得到像素
  let x = Math.floor(_x / resolution);
  let y = Math.floor(_y / resolution);
  return [x, y];
};

// 像素转3857
export const px2Mercator = (px, py, zoom) => {
  const resolution = getResolution(zoom);
  const x = resolution * px;
  const y = resolution * py;
  return [x, y];
};
